// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------
// Modification history:
// feature: Code style modification
// ------------------------------------------------------------------

#ifndef INCLUDE_EDDS_RTPS_WRITER_LOCATORSELECTORSENDER_HPP_
#define INCLUDE_EDDS_RTPS_WRITER_LOCATORSELECTORSENDER_HPP_

#include <edds/rtps/common/LocatorSelector.hpp>
#include <edds/rtps/messages/RTPSMessageSenderInterface.hpp>
#include <ertps/utils/collections/ResourceLimitedVector.hpp>

#include <mutex>

namespace evbs {
namespace ertps {
namespace rtps {

class RTPSWriter;

/*!
 * Class used by writers to inform a RTPSMessageGroup object which remote participants will be
 * addressees of next RTPS submessages.
 */
class LocatorSelectorSender : public RTPSMessageSenderInterface {
 public:
    LocatorSelectorSender(RTPSWriter& writer, const ResourceLimitedContainerConfig matched_readers_allocation)
        : locator_selector(matched_readers_allocation),
          all_remote_readers(matched_readers_allocation),
          all_remote_participants(matched_readers_allocation),
          writer_(writer) {}

    bool destinations_have_changed() const override { return false; }

    /*!
     * Get a GUID prefix representing all destinations.
     *
     * @return If only one remote participant is an addressee, return its GUIDPrefix_t.
     * c_GuidPrefix_Unknown otherwise.
     */
    GuidPrefix_t destination_guid_prefix() const override {
        return (all_remote_participants.size() == 1U) ? all_remote_participants.at(0U) : c_GuidPrefix_Unknown;
    }

    /*!
     * Get the GUID prefix of all the destination participants.
     *
     * @return a const reference to a vector with the GUID prefix of all destination participants.
     */
    const std::vector<GuidPrefix_t>& remote_participants() const override { return all_remote_participants; }

    /*!
     * Get the GUID of all destinations.
     *
     * @return a const reference to a vector with the GUID of all destinations.
     */
    const std::vector<GUID_t>& remote_guids() const override { return all_remote_readers; }

    /*!
     * Send a message through this interface.
     *
     * @param message Pointer to the buffer with the message already serialized.
     */
    bool send(CDRMessage_t* message) const override;

    /*!
     * Lock the object.
     *
     * This kind of object needs to be locked because could be used outside the writer's mutex.
     */
    void lock() override { mutex_.lock(); }

    /*!
     * Unlock the object.
     */
    void unlock() override { mutex_.unlock(); }

    ertps::rtps::LocatorSelector locator_selector;

    ResourceLimitedVector<GUID_t> all_remote_readers;

    ResourceLimitedVector<GuidPrefix_t> all_remote_participants;

 private:
    RTPSWriter& writer_;

    std::recursive_mutex mutex_;
};

}  // namespace rtps
}  // namespace ertps
}  // namespace evbs
#endif  // INCLUDE_EDDS_RTPS_WRITER_LOCATORSELECTORSENDER_HPP_
